<?php

namespace app\h7_tool\controller\pc;

use xsframe\exception\ApiException;

use xsframe\util\FileUtil;
use xsframe\util\RandomUtil;

class Upload extends Base
{
    /**
     * @return array
     * @throws ApiException
     */
    public function index()
    {
        $field = $this->params["fileKey"] ?? 'file';
        $type  = $this->params["fileType"] ?? 0;

        // 1图片 2视频MP4 3语音MP3 0其他
        switch ($type) {
            case 0:
                $filesRet = self::upload($field);
                break;
            case 1:
                $filesRet = self::uploadImage($field);
                break;
            case 2:
                $filesRet = self::uploadVideo($field);
                break;
            case 3:
                $filesRet = self::uploadVoice($field);
                break;
            default:
                $filesRet = [];
                break;
        }

        $result = [
            'files' => $filesRet
        ];
        return $this->success($result);
    }

    /**
     * 上传图片
     * @param $type
     * @param $field
     * @return array
     * @throws ApiException
     */
    private function uploadImage($field)
    {
        if (empty($field) || empty($_FILES[$field]['name'])) {
            throw new ApiException('请选择要上传的图片');
        }

        $files  = $_FILES[$field];
        $result = array();

        if (is_array($files["name"])) {
            foreach ($files["name"] as $key => $name) {
                if (strrchr($name, ".") === false) {
                    $name = $name . ".jpg";
                }
                $file    = array("name" => $name, "type" => $files["type"][$key], "tmp_name" => $files["tmp_name"][$key], "error" => $files["error"][$key], "size" => $files["size"][$key]);
                $files[] = $this->upload($file, 1, 'image');
            }
        } else {
            if (strrchr($files["name"], ".") === false) {
                $files["name"] = $files["name"] . ".jpg";
            }
            $result[] = $this->upload($_FILES[$field], 1, 'image');
        }

        return $result;
    }

    /**
     * 上传视频
     * @param $type
     * @param $field
     * @return array
     * @throws ApiException
     */
    private function uploadVideo($field)
    {
        if (empty($field) || empty($_FILES[$field]['name'])) {
            throw new ApiException('请选择要上传的视频');
        }

        $files = $_FILES[$field] ?? $_FILES;

        $result   = array();
        $result[] = $this->upload($files, 2, 'video');

        return $result;
    }

    /**
     * 上传音频
     * @param $type
     * @param $field
     * @return array
     * @throws ApiException
     */
    private function uploadVoice($field)
    {
        if (empty($field) || empty($_FILES[$field]['name'])) {
            throw new ApiException('请选择要上传的音频');
        }

        $files = $_FILES[$field];

        $result   = array();
        $result[] = $this->upload($files, 3, 'voice');

        return $result;
    }

    /**
     * 上传文件
     * @param $uploadFile
     * @param int $type
     * @param string $uploadType
     * @return array
     * @throws ApiException
     */
    private function upload($uploadFile, $type = 0, $uploadType = 'image')
    {
        $rootPath = $this->iaRoot . "/public/attachment/";

        // 文件类型
        $folderKey = !empty($type) ? $type : '';

        $path = $uploadType . "s" . "/" . $this->uniacid . "/" . $this->module . "/" . date('Y/m/');
        if (!is_dir($rootPath . $path . $folderKey . "/")) {
            FileUtil::mkDirs($rootPath . $path . $folderKey . "/");
        }

        $ext = $this->getFileExt($uploadFile, $uploadType);

        $fileName = $this->file_random_name($path, $ext, (empty($folderKey) ? "" : ($folderKey . "/")), 20);
        $filePath = $path . $fileName;

        // 不压缩
        move_uploaded_file($uploadFile['tmp_name'], $rootPath . $filePath);

        $data = [
            'url'      => tomedia(trim($filePath)),
            'filename' => $filePath,
        ];

        return $data;
    }

    /**
     * 获取文件后缀
     * @param $file
     * @param string $type
     * @return mixed|string
     * @throws ApiException
     */
    private function getFileExt($file, $type = 'image')
    {
        $harmType = array('asp', 'php', 'jsp', 'js', 'css', 'php3', 'php4', 'php5', 'ashx', 'aspx', 'exe', 'cgi');
        if (empty($file)) {
            throw new ApiException('没有上传内容');
        }
        if (!in_array($type, array('image', 'thumb', 'voice', 'video', 'audio', 'file'))) {
            throw new ApiException('未知的上传类型');
        }

        $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));

        $allowExt = [];
        $limit    = 1024 * 10;
        switch ($type) {
            case 'image':
                $allowExt = array('gif', 'jpg', 'jpeg', 'bmp', 'png', 'ico', 'heic');
                $limit    = $limit * 1;
                break;
            case 'thumb':
                $allowExt = array('gif', 'jpg', 'jpeg', 'bmp', 'png', 'ico', 'heic');
                $limit    = $limit * 1;
                break;
            case 'voice':
                $allowExt = array('mp3', 'wma', 'wav', 'amr', 'pcm', 'm4a', 'mp4', '3gp', 'aac');
                break;
            case 'audio':
                $allowExt = array('mp3', 'wma', 'wav', 'amr', 'pcm', 'm4a', 'mp4', '3gp', 'aac');
                $limit    = $limit * 1;
                break;
            case 'file':
                $allowExt = array('doc', 'docx', 'xls', 'xlsx');
                $limit    = $limit * 1;
                break;
            case 'video':
                $allowExt = array('rm', 'rmvb', 'wmv', 'avi', 'mpg', 'mpeg', 'mp4');
                $limit    = $limit * 1;
                break;
        }

        if (!in_array(strtolower($ext), $allowExt) || in_array(strtolower($ext), $harmType)) {
            throw new ApiException('不允许上传此类文件' . $ext);
        }

        if (!empty($limit) && $limit * 1024 < filesize($file['tmp_name'])) {
            throw new ApiException('上传的文件超过大小限制，请上传小于 {$limit}k 的文件');
        }

        return $ext;
    }

    // 生成文件名称
    private function file_random_name($dir, $ext, $preFix = '', $length = 30)
    {
        do {
            $filename = (empty($preFix) ? '' : $preFix . "_") . RandomUtil::random($length) . '.' . $ext;
        } while (file_exists($dir . $filename));
        return $filename;
    }

    /**
     * 压缩图片
     * @param $imgsrc
     * @param $imgdst
     * @param int $widthPer
     */
    private function compressedImage($imgsrc, $imgdst, $widthPer = 480)
    {
        list($width, $height, $type) = getimagesize($imgsrc);

        $new_width  = $width; //压缩后的图片宽
        $new_height = $height; //压缩后的图片高

        if ($width >= $widthPer) {
            $per        = $widthPer / $width; //计算比例
            $new_width  = $width * $per;
            $new_height = $height * $per;
        }

        switch ($type) {
            case 1:
                $gifType = $this->checkGifCartoon($imgsrc);
                if ($gifType) {
                    header('Content-Type:image/gif');
                    $image_wp = imagecreatetruecolor($new_width, $new_height);

                    //分配颜色 + alpha，将颜色填充到新图上
                    $alpha = imagecolorallocatealpha($image_wp, 0, 0, 0, 127);
                    imagefill($image_wp, 0, 0, $alpha);

                    $image = imagecreatefromgif($imgsrc);
                    imagecopyresampled($image_wp, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);

                    //将源图拷贝到新图上，并设置在保存 PNG 图像时保存完整的 alpha 通道信息
                    imagesavealpha($image_wp, true);

                    //90代表的是质量、压缩图片容量大小
                    imagepng($image_wp, $imgdst);

                    imagedestroy($image_wp);
                    imagedestroy($image);
                }
                break;
            case 2:
                header('Content-Type:image/jpeg');
                $image_wp = imagecreatetruecolor($new_width, $new_height);

                //分配颜色 + alpha，将颜色填充到新图上
                $alpha = imagecolorallocatealpha($image_wp, 0, 0, 0, 127);
                imagefill($image_wp, 0, 0, $alpha);

                $image = imagecreatefromjpeg($imgsrc);
                imagecopyresampled($image_wp, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);

                //将源图拷贝到新图上，并设置在保存 PNG 图像时保存完整的 alpha 通道信息
                imagesavealpha($image_wp, true);

                //90代表的是质量、压缩图片容量大小
                imagejpeg($image_wp, $imgdst, 90);
                // imagepng($image_wp, $imgdst);

                imagedestroy($image_wp);
                imagedestroy($image);
                break;
            case 3:
                header('Content-Type:image/png');
                $image_wp = imagecreatetruecolor($new_width, $new_height);

                //分配颜色 + alpha，将颜色填充到新图上
                $alpha = imagecolorallocatealpha($image_wp, 0, 0, 0, 127);
                imagefill($image_wp, 0, 0, $alpha);

                $image = imagecreatefrompng($imgsrc);
                imagecopyresampled($image_wp, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);

                //将源图拷贝到新图上，并设置在保存 PNG 图像时保存完整的 alpha 通道信息
                imagesavealpha($image_wp, true);

                //90代表的是质量、压缩图片容量大小
                imagejpeg($image_wp, $imgdst, 90);
                // imagepng($image_wp, $imgdst);

                imagedestroy($image_wp);
                imagedestroy($image);
                break;
        }
    }

    /**
     * 判断是否gif动画
     * @param $imageFile
     * @return boolean t 是 f 否
     */
    private function checkGifCartoon($imageFile)
    {
        $fp         = fopen($imageFile, 'rb');
        $image_head = fread($fp, 1024);
        fclose($fp);
        return preg_match("/" . chr(0x21) . chr(0xff) . chr(0x0b) . 'NETSCAPE2.0' . "/", $image_head) ? false : true;
    }

}